<!-- 
使用方式如下
<customSelect v-model="formData.custom" :fn="getPoint" dataRoot="stations" label="station_name" value="station_id" /> 
-->
<template>
  <el-select
    v-model="selectedValue"
    :placeholder="placeholder"
    :disabled="disabled"
    clearable
    filterable
    @clear="handleClear"
    @change="handleChange"
  >
    <el-option
      v-for="item in customsList"
      :key="item[props?.value]"
      :label="item[props?.label]"
      :value="item[props?.value]"
    />
    <template #header>
      <el-input v-model.trim="querySearch" clearable :maxlength="32" placeholder="请输入查询" @clear="handleClear">
        <template #append>
          <el-button @click="handleSearch" :icon="Search" />
        </template>
      </el-input>
    </template>
    <template v-if="bottomCommit" #footer>
      <Pagination
        v-model:page="pagination.page"
        v-model:limit="pagination.limit"
        :total="total"
        :pageSizes="pageSize"
        @pagination="getSelect"
      />
    </template>
  </el-select>
</template>

<script setup lang="ts">
import { ref, reactive } from "vue";
import Pagination from "@/components/Pagination/index.vue";
import { Search } from "@element-plus/icons-vue";
interface Props {
  bottomCommit?: boolean; // 是否有分页
  params?: object; // 入参
  dataRoot: string; // 匹配后台数据出参字段
  fn?: Function | string; // 接口
  label: string; // 展示名称字段名
  value: string; // 选中的值字段名
  placeholder?: string; // 提示
  disabled?: boolean; // 是否禁用
  query?: string; // 搜索字段名
  pageSize?: number[]; // 分页
  fieldName?: string | number | undefined; // 回显名称
  modelValue?: string | number; // 选中的回显id【用于本身组件内，组件外不适用】
}
const props = withDefaults(defineProps<Props>(), {
  bottomCommit: true,
  placeholder: "请选择",
  disabled: false,
  query: "query",
  fieldName: undefined,
  pageSize: () => [200, 400, 600, 800, 1000],
});
// 监听入参变化
watch(
  () => props.params,
  () => {
    getSelect();
  }
);
onBeforeMount(() => {
  if (props.fn) {
    pagination.page = 1;
    querySearch.value = props?.fieldName || undefined;
    getSelect(querySearch.value);
  }
});
// 监听事件
const emits = defineEmits(["update:modelValue", "handleChange"]);
// 分页
let pagination = reactive<{ page: number; limit: number }>({
  page: 1,
  limit: props.pageSize[0],
});
const total = ref<number>(0);
// 下拉数据源
const customsList = ref(new Array<any>());
// Value值
const selectedValue = ref<string | number | undefined>();
// 监听回显Value值
watch([customsList, () => props.modelValue], ([newOptions, newModelValue]) => {
  if (newOptions.length === 0) return; // 下拉数据源加载未完成不回显
  if (newModelValue == undefined) {
    selectedValue.value = undefined;
    return;
  }
  if (typeof newOptions[0].value === "number") {
    selectedValue.value = Number(newModelValue);
  } else if (typeof newOptions[0].value === "string") {
    selectedValue.value = String(newModelValue);
  } else {
    selectedValue.value = newModelValue;
  }
});
// select选择器回调
const handleChange = (_val?: string | number | undefined | object) => {
  // 选中的单个id
  emits("update:modelValue", _val);
  const findObj = customsList.value.find((item) => item[props?.value] === _val);
  // 获取选中的整个对象
  emits("handleChange", findObj);
};
// 请求接口
const querySearch = ref<any>(undefined);
const getSelect = async (queryName?: string) => {
  querySearch.value = typeof queryName === "object" ? undefined : queryName; // 区分是分页传过来还是select选择器搜索
  const params = {
    [props?.query]: querySearch.value,
    ...props.params,
    ...pagination,
  };
  try {
    if (props.fn) {
      const res = typeof props.fn === "string" ? "" : await props.fn(params);
      if (res) {
        const obj: any = res[props.dataRoot];
        const { totalCount, items } = obj;
        customsList.value = items;
        total.value = totalCount;
      } else {
        customsList.value = [];
        total.value = 0;
      }
    } else {
      customsList.value = [];
      total.value = 0;
    }
  } catch (e: any) {
    customsList.value = [];
    total.value = 0;
  }
};
// 输入框搜索
const handleSearch = () => {
  if (!querySearch.value) return;
  getSelect(querySearch.value);
};
// 搜索清空
const handleClear = () => {
  querySearch.value = undefined;
  getSelect(querySearch.value);
};
</script>
